19.14 Die beiden »Splitter«-Steuerelemente  
Im Windows-Explorer befindet sich zwischen dem durch ein TreeView-Steuerelement darstellbaren Teilfenster und dem rechten Teilfenster ein Steuerelement, das mit der Maus gegriffen und verschoben werden kann. Dieses wird durch die Klasse Splitter beschrieben.
Ein Splitter (Teiler) ist immer an einem anderen Steuerelement angedockt, dessen Größe direkt vom Teiler verändert wird. Im Windows-Explorer ist es das TreeView-Steuerelement, das selbst am linken Fensterrand angedockt ist. Rechtsbündig befindet sich am TreeView der Splitter. Das Steuerelement, das sich auf der nicht angedockten Seite des Splitters befindet, füllt häufig alleine den verbleibenden Clientbereich aus.
Mit einer Ergänzung zum altbewährten Splitter-Control wartet .NET Framework 2.0 auf und bietet auch noch das sehr ähnliche Steuerelement SplitContainer an. Es vereinfacht die Aufteilung von Clientbereichen und wartet auch mit ein paar zusätzlichen Eigenschaften auf, die Splitter nicht hat.
19.14.1 Das Steuerelement »Splitter«  
Die Eigenschaft »Dock«
Angedockt werden Steuerelemente an den Containerrand mit der Eigenschaft Dock, die insgesamt sechs Werte zulässt, die in der Enumeration DockStyle definiert sind. Als Container kann nicht nur die Form, sondern beispielsweise auch ein Panel-Steuerelement dienen.
Tabelle 19.21 Konstanten der Enumeration »DockStyle«
| Member
|
Beschreibung
|
| None
|
(Standard) Das Steuerelement wird nicht angedockt.
|
| Top
|
Der obere Rand des Steuerelements wird am oberen Rand des Container-Steuerelements angedockt.
|
| Bottom
|
Der untere Rand des Steuerelements wird am unteren Rand des Container-Steuerelements angedockt.
|
| Left
|
Der linke Rand des Steuerelements wird am linken Rand des Container-Steuerelements angedockt.
|
| Right
|
Der rechte Rand des Steuerelements wird am rechten Rand des Container-Steuerelements angedockt.
|
| Fill
|
Alle Ränder des Steuerelements werden an die Ränder des Container-Steuerelements angedockt und die Größe entsprechend angepasst.
|
Um zum gewünschten Ergebnis zu kommen, darf die Dock-Eigenschaft der Steuerelemente nicht unüberlegt festgelegt werden. Machen wir uns das an einem Beispiel klar, und nehmen wir deshalb an, wir wollten in einer Form zwei Schaltflächen so platzieren, dass beide nebeneinander liegen. Ziehen wir zunächst den ersten Button (Name = Button1) aus der Toolbox in die Form und stellen seine Dock-Eigenschaft auf DockStyle.Fill ein. Danach wird der zweite Button in die Form gezogen (Name = Button2) und seine Dock-Eigenschaft auf DockStyle.Left festgelegt.
Die Ansicht zur Laufzeit sehen Sie in der folgenden Abbildung, in der button1 zu Verdeutlichung fokussiert ist.
 Hier klicken, um das Bild zu Vergrößern
Abbildung 19.22 »Button2« überdeckt »Button1«.
Der zuerst in die Form gezogene Button wird durch den zweiten verdeckt. Dadurch, dass die zuerst instanziierte Schaltfläche bedingt durch DockStyle.Fill den gesamten unbesetzten Bereich des Containers beansprucht, wird der zweite Button nach seiner Erstellung über dem ersten angezeigt.
Legen wir die Dock-Eigenschaft des zuerst instanziierten Buttons auf DockStyle.Left fest und die des zweiten auf DockStyle.Fill, haben wir das angestrebte Ergebnis – beide Schaltflächen werden vollständig sichtbar in der Form nebeneinander angeordnet, denn die zweite Schaltfläche kann trotz DockStyle.Fill nur den Bereich ihres Containers beanspruchen, der noch nicht von einem anderen Steuerelement besetzt ist – vorausgesetzt, die anderen Steuerelemente haben eine von DockStyle.None abweichende Einstellung.
 Hier klicken, um das Bild zu Vergrößern
Abbildung 19.23 »Button1« und »Button2« werden vollständig angezeigt.
Verantwortlich für die unterschiedliche Darstellungsweise ist die z-Reihenfolge. Das Steuer-element, das als erstes in eine Form eingefügt wird, steht in der z-Reihenfolge ganz unten, das als letztes eingefügte ganz oben. In der Auflistung der Steuerelemente der Form ControlCollection hat die zuletzt eingefügte Komponente den Index 0.
Um den Sachverhalt weiter zu vertiefen, wollen wir nun noch überlegen, wie wir die in Abbildung 19.24 gezeigte Anordnung der Schaltflächen realisieren können.
 Hier klicken, um das Bild zu Vergrößern
Abbildung 19.24 Form mit drei angedockten Schaltflächen
Die Schaltfläche, die in ihrem Container die Dock-Einstellung voll nutzen kann, ist die oberste (Dock=DockStyle.Top). Wir erstellen diese also als erste. Das weitere Vorgehen lässt zwei Alternativen zu.
|
Wir können der zweiten Schaltfläche, die wir erstellen, die Einstellung DockStyle.Left zuweisen und der dritten DockStyle.Fill. Da sich diese beiden Objekte jeweils nur in den frei verfügbaren Clientbereich ihres Containers positionieren, der sich um die Höhe der zuerst erstellten Schaltfläche verringert hat, wird die zuerst erzeugte Schaltfläche nicht überdeckt. |
|
Die andere Alternative wäre es, der zweiten Schaltfläche DockStyle.Right und der dritten DockStyle.Fill zuzuweisen. |
Fassen wir unsere Erkenntnisse über die Entwicklung von Benutzeroberflächen mit angedockten Steuerelementen in zwei kurzen Merksätzen zusammen.
|
Erzeugen Sie zuerst das Steuerelement, das an einen Fensterrand angedockt werden muss. Dieses Steuerelement befindet sich dann gleichzeitig auch an unterster Stelle in der z-Reihenfolge.
Die weitere Einfügereihenfolge muss in sinnvoller Weise so erfolgen, bis das letzte Element erstellt wird, dessen Dock-Einstellung immer DockStyle.Fill ist.
|
Das Verhalten eines Teilers richtig festlegen
Schlagen wir jetzt den Bogen zum Splitter-Steuerelement und nehmen wir an, dass wir die von den beiden Schaltflächen in der Abbildung 19.23 beanspruchten Teilbereiche durch einen Teiler verschieben wollen. Dazu müssen wir die beiden Steuerelemente in derselben Reihenfolge und mit derselben Dock-Einstellung erstellen, wie es in den beiden Merksätzen oben beschrieben ist. Der einzige Unterschied ist lediglich, dass nach dem Andocken der ersten Schaltfläche an den Formrand ein Splitter hinzugefügt wird, der an die erste Schaltfläche angedockt wird. Die Schritte sind demnach wie folgt:
|
Einfügen von Button1 |
|
Einstellen der Eigenschaft button1.Dock=DockStyle.Left |
|
Einfügen von Splitter1 |
|
Einstellen der Eigenschaft splitter1.Dock=DockStyle.Left |
|
Einfügen von Button2 |
|
Einstellen der Eigenschaft button2.Dock=DockStyle.Fill |
Nun sehen wir uns auch noch an, wie einfach es ist, die Teilbereiche der drei Schaltflächen der Abbildung 19.24 durch Teiler verschiebbar zu machen:
|
Einfügen von Button1 |
|
Einstellen der Eigenschaft Button1.Dock=DockStyle.Top |
|
Einfügen von Splitter1 |
|
Einstellen der Eigenschaft Splitter1.Dock=DockStyle.Top |
|
Einfügen von Button2 |
|
Einstellen der Eigenschaft Button2.Dock=DockStyle.Left |
|
Einfügen von Splitter2 |
|
Einstellen der Eigenschaft Splitter1.Dock=DockStyle.Left |
|
Einfügen von Button3 |
|
Einstellen der Eigenschaft Button3.Dock=DockStyle.Fill |
Eigenschaften des »Splitter«-Steuerelements
Die Klasse Splitter ist direkt aus der Klasse Control abgeleitet und erbt damit deren Eigenschaften. Zusätzliche klassenspezifische Eigenschaften gibt es nicht sehr viele, und das macht die Entwicklung – abgesehen von der korrekten Positionierung – sehr einfach.
Mit den beiden Eigenschaften MinSize und MinExtra geben Sie an, wie klein das neben dem Splitter-Steuerelement befindliche Steuerelement werden darf. Da ein Teiler immer zwischen zwei Steuerelementen zu finden ist, bezieht sich MinSize auf das Steuerelement, das am Rand des Containers angedockt ist, und MinExtra auf das andere Steuerelement.
Mit diesen Einstellungen, die standardmäßig 25 Pixel haben, wird vermieden, dass das zusammengestauchte Steuerelement so klein wird, dass es vom Anwender nicht mehr erkannt und bedient werden kann. Einschränkend muss allerdings auch angemerkt werden, dass bei einer Veränderung der Formgröße die Eigenschaften MinSize und MinExtra nicht berücksichtigt werden und unter Umständen ein Steuerelement und auch der Splitter nicht mehr sichtbar sind. Um das zu vermeiden, müssen Sie beispielsweise im Resize-Ereignis der Form die Splitterposition parallel zur Veränderung der Formabmessungen anpassen. Hilfreich ist dabei die Eigenschaft SplitPosition des Splitters, welche die augenblickliche Position zurückliefert.
Mit BorderStyle lässt sich generell immer die Rahmendarstellung eines Steuerelements beeinflussen. Die Standardeinstellung ist BorderStyle=BorderStyle.None. Mit BorderStyle.FixedSingle können Sie aber auch eine einfache Umrandung einstellen oder mit BorderStyle.Fixed3D eine dreidimensionale.
Tabelle 19.22 Eigenschaften des »Splitter«-Steuerelements
| Eigenschaft
|
Beschreibung
|
| MinSize
|
Legt den Mindestabstand zwischen dem Splitter und dem Rand des Containers fest, an den das Steuerelement angedockt ist.
|
| MinExtra
|
Legt den Mindestabstand fest, der zwischen dem Splitter und dem Rand der gegenüberliegenden Seite des Containers (oder dem nächsten an dieser Seite angedockten Steuerelement) bestehen soll.
|
| SplitPosition
|
Ruft den Abstand zwischen dem Splitter-Steuerelement und dem Rand des Containers ab, an den das Steuerelement angedockt ist.
|
Ereignisse
Während der Teiler bewegt wird, treten unablässig SplitterMoving-Ereignisse auf, vergleichbar mit den Ereignissen MouseMove, wenn der Mauszeiger über eine Komponente bewegt wird. Das Loslassen der Maustaste wird von der einmaligen Auslösung von SplitterMoved begleitet. Danach wird die Größe der beiden Steuerelemente geändert.
| Public Event SplitterMoved As SplitterEventHandler
|
| Public Event SplitterMoving As SplitterEventHandler
|
Bei der Auslösung der Ereignisse wird ein Objekt vom Typ SplitterEventArgs mit den folgenden Eigenschaften übergeben:
Tabelle 19.23 Eigenschaften eines »SplitterEventArgs«-Objekts
| Eigenschaft
|
Beschreibung
|
| X
|
Gibt die x-Koordinate des Mauszeigers zurück.
|
| Y
|
Gibt die y-Koordinate des Mauszeigers zurück.
|
| SplitX
|
Ruft die x-Koordinate der oberen linken Ecke des Splitters ab.
|
| SplitY
|
Ruft die y-Koordinate der oberen linken Ecke des Splitters ab.
|
Die Eigenschaften SplitX und SplitY geben die Position der linken oberen Ecke des Teilers zurück – relativ zum Clientbereich. Das bedeutet auch, dass SplitX bei horizontalen Teilern immer 0 ist, während SplitY bei vertikalen Teilern immer 0 aufweist.
Sie sollten beachten, dass beim Ereignis SplitterMoving die x- und y-Koordinaten auch dann die Mauszeigerkoordinaten wiedergeben, wenn sich das Ziehen des Teilers aus dem Anzeigebereich der Form hinausbewegt. Tatsächlich wird dann der splittertypische Mauszeiger mit seinen zwei vertikalen oder horizontalen Linien auch außerhalb des Formularbereichs angezeigt, wenn man die Maustaste nicht loslässt. Sogar negative Koordinaten sind deshalb möglich. Der Auswertbarkeit der Positionskoordinaten im Programmcode sind also Grenzen gesetzt.
19.14.2 Das Steuerelement »SplitContainer«  
Zu den neuen Steuerelementen des .NET Frameworks gehört auch das an Splitter angelehnte sehr ähnliche Steuerelement SplitContainer. Es besteht aus einer verschiebbaren Leiste, die den Anzeigebereich eines Containers in zwei Bereiche mit veränderbarer Größe teilt. Die beiden Bereiche werden jeweils durch ein Panel beschrieben, in denen Sie nach Belieben die Steuerelemente unterbringen können, welche die Form benötigt. Sie können mehrere SplitContainer ineinander verschachteln, so dass Sie auch sehr komplexe Fensterteilungen erstellen können. Im Gegensatz zu dem im vorherigen Kapitel beschriebenen Splitter ist das Arbeiten mit SplitContainer intuitiver und weist zusätzliche Eigenschaften auf. Beispielsweise kann nun auch der Benutzer mit den Steuerungstasten der Tastatur den Splitter zwischen den beiden Teilflächen verschieben. Mit SplitterIncrement legen Sie fest, wie groß dabei die Schrittweite in Pixel ist. Ein Pixel ist hierbei die Voreinstellung.
Die Orientation-Eigenschaft des SplitContainer-Steuerelements bestimmt die Richtung des Splitters. Wenn diese Eigenschaft auf Vertical festgelegt ist, verläuft der Splitter daher von oben nach unten und erstellt eine linke und eine rechte Fläche. Das ist die Standardvorgabe. Panel1 ist dabei der Teilbereich, der je nach Orientierung entweder links vom Teiler oder oberhalb angeordnet ist.
Sie können eines der beiden Panel fixieren. Das hat zur Folge, dass dieses Panel bei einer Größenänderung der Form seine ursprüngliche Größe beibehält. Möchten Sie verhindern, dass der Benutzer den Teiler verschiebt, legen Sie IsSplitterFixed=True fest. Eines der beiden Panel auszublenden, ist sehr einfach. Legen Sie dazu nach Bedarf eine der beiden Eigenschaften Panel1Collapsed oder Panel2Collapsed auf True fest. Darf jedes der beiden Panel eine festgelegte Mindestgröße nicht unterschreiten, stellen Sie diese in Panel1MinSize bzw. Panel2MinSize ein.
Zu guter Letzt muss auch erwähnt werden, dass Sie über Panel1 und Panel2 Zugriff auf die beiden Teilflächen bekommen und diese individuell einstellen können.
Alle diese aufgeführten Eigenschaften machen das Steuerelement SplitContainer natürlich attraktiver als das langsam in die Tage kommende Splitter-Steuerelement. Microsoft empfiehlt in seiner Dokumentation, SplitContainer dem Splitter-Steuerelement vorzuziehen.
Tabelle 19.24 Eigenschaften eines »SplitContainer«-Steuerelements
| Eigenschaften
|
Beschreibung
|
| FixedPanel
|
Legt fest, ob einer der beiden Teilbereiche bei einer Größenänderung der Form seine Größe beibehält.
|
| IsSplitterFixed
|
Legt fest, ob der Splitter verschoben werden kann.
|
| Orientation
|
Legt die Ausrichtung des Splitters fest.
|
| Panel1
|
Liefert die Referenz auf das erste Panel (je nach Ausrichtung des Splitters das linke bzw. obere).
|
| Panel1Collapsed
|
Legt fest, ob Panel1 ausgeblendet ist.
|
| Panel1MinSize
|
Legt die minimale Breite von Panel1 fest.
|
| Panel2
|
Liefert die Referenz auf das zweite Panel (je nach Ausrichtung des Splitters das rechte bzw. untere).
|
| Panel2Collapsed
|
Legt fest, ob Panel2 ausgeblendet ist.
|
| Panel2MinSize
|
Legt die minimale Breite von Panel2 fest.
|
| SplitterDistance
|
Bestimmt den Pixelabstand des Teilers von der linken oder oberen Kante des Steuerelements.
|
| SplitterIncrement
|
Bestimmt die Anzahl der Pixel, um die sich der Teiler bewegt.
|
| SplitterWidth
|
Legt die Breite des Splitters in Pixel fest.
|
|